home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / ab20_archive / utilities / file / whereis.lzh / whereis.c < prev    next >
C/C++ Source or Header  |  1991-02-16  |  20KB  |  726 lines

  1. /***************************************************************************
  2.  * Program: Whereis (searches for a filename on your [hard]-disk)          *
  3.  * Version: 1.22 for AMIGA-Computers. Last-Update:  Saturday 16-Feb-1991   *
  4.  * Whereis.c by R. Bless 1989/90/91. All Rights reserved! Program (exe) is *
  5.  * free distributable. Compilable under Aztec 3.6a.                        *
  6.  * ------------------------------ NOTE :---------------------------------- *
  7.  * No redistribution of a changed source and/or executable without         *
  8.  * permission of the author!!! Please ask me first. See address below.     *
  9.  * ----------------------------------------------------------------------- *
  10.  * I'm fed up with all 'whereis' or 'wo' utilities that I had, because the *
  11.  * one is always case sensitive and can't be aborted, the other is         *
  12.  * horribly slow and can't handle wildcards >:-(! So here is my product    *
  13.  * which uses no recursive procedures.                                     *
  14.  * Written from 17-10-89 to 24-10-89 (first version then addups)           *
  15.  * (C)opyright by Roland Bless (Byteable Software Products)                *
  16.  ***************************************************************************/
  17. /*
  18. Any comments or bug-reports to:
  19.  
  20. R o l a n d   B l e s s |UUCP/USENET: rob@spirits.ka.sub.org                |
  21. Kriegsstrasse 129       |BITNET: UKG5@DKAUNI2.BITNET      FAX: +49211623818 |
  22. 7500 Karlsruhe - FRG
  23. voice +49 721 857328
  24.  
  25.    Please don't think that I'm not familiar with gotos or breaks and
  26.    such things of not structured languages, but I won't go back to
  27.    BASIC-Level with a jump here or there and you don't know where you are...
  28.    In a mood I just decided to leave these things out... Maybe I should
  29.    write in Pascal or Modula? :-)                                            */
  30. /*
  31.    future adds
  32.        -s|u|D date search
  33.        -l list format  */
  34.  
  35. #include <stdio.h>
  36. #include <ctype.h>
  37. #include <exec/memory.h>
  38. #include <libraries/dos.h>
  39. #include <libraries/dosextens.h>
  40.  
  41. #include "date.h"                  /* my own date function */
  42.  
  43. #define MAXPATH 256                /* Maximum pathname length  */
  44. #define MEMTYPE 0L                 /* Memtype: Fast or Chipmem */
  45. #define true 1                     /* Right boolean values, because */
  46. #define false 0                    /* typedef short BOOL, but TRUE= 1L! */
  47. #define ON true
  48. #define OFF false
  49.  
  50. struct ListType
  51. {
  52.   struct FileInfoBlock FIBlock;
  53.   struct FileLock      *FLock;
  54.   struct ListType  *prev;
  55. };
  56.  
  57.             /**** external functions & variables ****/
  58.  
  59. extern int Enable_Abort;
  60.  
  61. void *Lock();
  62. void *AllocMem();
  63. void *ParentDir();
  64. extern void date();
  65. struct Process *FindTask();
  66. struct MsgPort *CreatePort();
  67. long IsInteractive(), SetSignal();
  68. struct FileHandle *Input(), *Output();
  69. struct FileLock *CurrentDir();
  70.  
  71.                      /***** globals *****/
  72.  
  73. char MPath [256], c, casedep;            /* Global PathName (MainPath) */
  74. WORD  options= 0; /* options switches */
  75. WORD MPathPos= 0;
  76. struct StandardPacket *packet;
  77. struct MsgPort *replyport, *conid;
  78. struct Process *myprocess;
  79.  
  80. char *prgname;
  81. enum { CASESENSITIVE=1, DIRSONLY=2, FILESONLY=4, LONGPATH=8 , SIZE=16,
  82.        TIME=32, NOSUBDIRS=64, JUMPDIR=128 };
  83.       /* switches go here */
  84.  
  85. enum { NOMEM, NODIR, DESTROYEDENTRY, TOOMANYARGS, WRONGNAME, ILLEGALOPTION,
  86.        NOPATTERN, NOINPUT, STRANGE, INFO, USAGE };
  87.      /*** ErrorNumbers for ErrorHandle ***/
  88.  
  89. char *Msg[]=
  90. { "FATAL ERROR: Not enough memory available!\n",
  91.   "ERROR: Can't find that directory or device:",
  92.   "ERROR: Destroyed entry! Couldn't examine this '",
  93.   "ERROR: Can't handle so many arguments. See usage!\n",
  94.   "ERROR: Please no path in the filename/pattern! See usage!\n",
  95.   "ERROR: Illegal Option '",
  96.   "ERROR: I've no filepattern to search for!\n",
  97.   "ERROR: Input must be interactive! \n",
  98.   "STRANGE ERROR: Something strange happend...!\n",
  99.   "INFO: whereis V1.22 16-Feb-1991 by R. Bless.\n"
  100. };  /* Messages for ErrorHandle/Numbers */
  101.  
  102.                      /******************/
  103.  
  104. long
  105. Chk_Abort()
  106. {
  107.   return 0L;
  108. }
  109.  
  110. void ErrorHandle(ErrMsgNr)
  111. short ErrMsgNr;
  112. {
  113.   if (ErrMsgNr != USAGE)
  114.      fprintf(stderr, "%s- %s", prgname, Msg[ErrMsgNr]);
  115.   else
  116.   {
  117.      fprintf(stderr, "usage: %s [-acdfijnpst] [dev:path] filename.", prgname);
  118.      fprintf(stderr, " Wildcards *,? allowed.\n");
  119.   }
  120. }
  121.  
  122.  
  123. int SwitchRaw(RawMode)
  124. BOOL RawMode;
  125.  
  126. {
  127.   replyport= (struct MsgPort *) CreatePort(NULL, NULL);
  128.   if (!replyport)
  129.      return 1;
  130.  
  131.   packet= (struct StandardPacket *)
  132.           AllocMem((long)sizeof(*packet),MEMF_PUBLIC | MEMF_CLEAR);
  133.   if (!packet)
  134.   {
  135.     DeletePort(replyport);
  136.     return 1;
  137.   }
  138.  
  139.   /* init DOS-Packet */
  140.   packet->sp_Msg.mn_Node.ln_Name= (char *) &(packet->sp_Pkt); /* link packet- */
  141.   packet->sp_Pkt.dp_Link= &(packet->sp_Msg);                 /* to message    */
  142.   packet->sp_Pkt.dp_Port= replyport;                      /* set-up reply port*/
  143.   packet->sp_Pkt.dp_Type= ACTION_SCREEN_MODE;        /* function */
  144.  
  145.   if (RawMode==ON)
  146.   {
  147.     packet->sp_Pkt.dp_Arg1= DOSTRUE;
  148.     fflush(stdout);
  149.   }
  150.   else
  151.   {
  152.     packet->sp_Pkt.dp_Arg1= DOSFALSE;
  153.   }
  154.   PutMsg(conid,packet);  /* send packet */
  155.   WaitPort(replyport); /* wait for packet to come back */
  156.   GetMsg(replyport);   /* pull message */
  157.   FreeMem(packet, (long) sizeof(*packet));
  158.   DeletePort(replyport);
  159.   return 0;
  160. }
  161.  
  162.  
  163. void printdate(ds)
  164. struct DateStamp *ds;
  165. {
  166.   struct date mydate;
  167.  
  168.   date(&mydate, ds->ds_Days);
  169.   fprintf(stdout," %02d-%02d-%02ld %02ld:%02ld:%02ld",
  170.           mydate.day, mydate.month, mydate.year-1900,
  171.           ds->ds_Minute/60L, ds->ds_Minute%60L, ds->ds_Tick/50L);
  172. }
  173.  
  174.  
  175. void Append(s, root)   /* Appends the dirname to MPath (MainPath) */
  176. char *s;
  177. BOOL root;
  178.  
  179. {
  180.   int p;
  181.  
  182.   for (p= 0; s[p]!= '\0'; p++)
  183.       MPath[MPathPos+p]= s[p];
  184.   MPath[MPathPos+p++]= root==true ? ':' : '/';
  185.   MPath[MPathPos+p]= '\0';
  186.   MPathPos+=p;
  187. }
  188.  
  189.  
  190. void InsertPath(s, root)   /* Inserts a dirname into MPath */
  191. char *s;
  192. struct FileLock *root;
  193.  
  194. {
  195.   int p,len;
  196.  
  197.   len= strlen(s)+1;
  198.   for (p= MPathPos; p >= 0; p--)
  199.       MPath[p+len]= MPath[p];
  200.   MPathPos+=len;
  201.   for (p= 0; s[p] != '\0'; p++)
  202.       MPath[p]= s[p];
  203.  
  204.   MPath[p]= root==NULL ? ':' : '/';
  205. }
  206.  
  207.  
  208. void Cut()           /* Removes the last dirname from MPath */
  209. {
  210.   if (MPathPos) --MPathPos;
  211.   while (--MPathPos>=0 && MPath[MPathPos] != '/' && MPath[MPathPos] != ':');
  212.   MPath[++MPathPos]= '\0';
  213. }
  214.  
  215.  
  216. struct FileLock *FindRoot(FL)   /* Climbs up to root-directory */
  217. struct FileLock *FL;
  218.  
  219. {
  220.   struct FileLock *PL;
  221.  
  222.   PL= FL;
  223.   while (FL= ParentDir(FL))
  224.   {
  225.     UnLock(PL);
  226.     PL=FL;
  227.   }
  228.   return PL;
  229. }
  230.  
  231.  
  232. long GetFullPath(path)    /* Get the full pathname */
  233. char *path;
  234.  
  235. {
  236.   struct FileLock *FL, *PL;
  237.   struct FileInfoBlock *FIB;
  238.   BOOL Error= false;
  239.  
  240.   FIB= (struct FileInfoBlock *)
  241.        AllocMem ((long) sizeof(struct FileInfoBlock), MEMTYPE);
  242.  
  243.   if (!FIB)
  244.   {
  245.     ErrorHandle(NOMEM);
  246.     Error= true;
  247.   }
  248.   else
  249.   if (!(FL= (struct FileLock *) Lock(path, (ULONG) ACCESS_READ)))
  250.   {
  251.     ErrorHandle(NODIR);
  252.     fprintf(stderr," %s\n", path);
  253.     Error= true;
  254.   }
  255.  
  256.   while (FL && !Error)
  257.   {
  258.     if (!Examine(FL, FIB))
  259.     {
  260.       ErrorHandle(DESTROYEDENTRY);
  261.       fprintf(stderr,"%s'. Very strange!\n", path);
  262.       Error= true;
  263.     }
  264.     else
  265.     {
  266.       InsertPath(FIB->fib_FileName, PL= ParentDir(FL));
  267.       UnLock (FL);
  268.       FL= PL;
  269.     }
  270.   }
  271.   if (FIB) FreeMem (FIB,(long) sizeof(struct FileInfoBlock));
  272.   if (FL) UnLock (FL);
  273.   return Error;
  274. }
  275.  
  276.  
  277. /* Wildcard handling, new routine since V1.19 */
  278.  
  279. BOOL
  280. Match(s, fpat)
  281. register char *s,*fpat;
  282. {
  283.   while (*fpat!='\0')
  284.   {
  285.     if (*fpat == '*')
  286.     {
  287.       while (*fpat=='*' || *fpat=='?')
  288.       {
  289.         fpat++;         /* skip following wildcards, until letter or \0 */
  290.       }
  291.       if (*fpat!='\0')        /* letter/pattern detected! */
  292.       {
  293.         while (*s!='\0' && (*s&casedep) != (*fpat&casedep))
  294.               s++;
  295.         if (*s=='\0') return NULL;
  296.       }
  297.       else
  298.          while (*s!='\0')    /* ingore all chars till end */
  299.                s++;
  300.     }
  301.     else
  302.     if (*fpat == '?')
  303.     {
  304.       fpat++;                    /* Just ignore that char */
  305.       if (*s!='\0') s++;
  306.     }
  307.     else
  308.     if ((*s&casedep) == (*fpat&casedep))
  309.     {
  310.       register char *stmp=s,*ptmp=fpat;
  311.  
  312.       /* test whether sub-string matches or not */
  313.       while (*stmp!='\0' && ((*stmp&casedep) == (*ptmp&casedep)))
  314.       {
  315.          stmp++;ptmp++;
  316.       }
  317.       if (*stmp=='\0' || *ptmp=='*' || *ptmp=='?' || *ptmp=='\0')
  318.       {
  319.         fpat=ptmp;s=stmp;     /* it does! next wildcard or so... */
  320.       }
  321.       else
  322.       {
  323.         s++;
  324.         while (*s!='\0' && (*s&casedep) != (*fpat&casedep)) s++;
  325.       }
  326.     }
  327.     else
  328.         return false;
  329.   }
  330.   return (*s=='\0' ? true : false);
  331. }
  332.  
  333.  
  334. /* Now comes the main-stuff!!! */
  335.  
  336. BOOL Search (path, fpat)       /* not recursive! */
  337. char *path, *fpat;
  338.  
  339. {
  340.   struct FileLock      *FL= NULL;
  341.   struct FileInfoBlock *FIB= NULL;
  342.   struct ListType  *LChainP= NULL, *OldLChainP= NULL;
  343.  
  344.   BOOL Error= false;
  345.   char cbuf;
  346.   int p;
  347.  
  348.   casedep= (options & CASESENSITIVE) ? 0xFF : 0x5F; /* Mask for match() */
  349.  
  350.   if (!fpat)
  351.   {
  352.     ErrorHandle(WRONGNAME);
  353.     Error= true;
  354.   }
  355.   else
  356.   if (path)
  357.   {
  358.      if (options & LONGPATH)
  359.         Error= GetFullPath(path); /* Full-Pathname */
  360.      else
  361.      {                            /* "short pathname" */
  362.        int p;
  363.  
  364.        for (p= 0; path[p]!= '\0'; p++)
  365.             MPath[MPathPos+p]= path[p];
  366.  
  367.        if (p>0)
  368.        {
  369.          p--;
  370.          if (MPath[MPathPos+p]!='/' && MPath[MPathPos+p]!=':')
  371.          {
  372.            p++; MPath[MPathPos+p]= '/';
  373.          }
  374.          p++;
  375.        }
  376.        else
  377.          MPathPos= 0;
  378.  
  379.        MPath[MPathPos+p]= '\0';
  380.        MPathPos+= p;
  381.      }
  382.   }
  383.  
  384.   if (!Error)
  385.   {
  386.     LChainP= (struct ListType *)
  387.              AllocMem ((long) sizeof(struct ListType), MEMTYPE);
  388.  
  389.     if (!LChainP)
  390.     {
  391.       ErrorHandle(NOMEM);
  392.       Error= true;
  393.     }
  394.     else
  395.     {
  396.       FIB= &LChainP->FIBlock;
  397.  
  398.       if (!(FL= (struct FileLock *) Lock(MPath, (ULONG) ACCESS_READ)))
  399.       {
  400.         ErrorHandle(NODIR);
  401.         fprintf(stderr," %s\n", MPath);
  402.         Error= true;
  403.       }
  404.       else
  405.       {
  406.         if (!path)
  407.            FL= FindRoot(FL);
  408.  
  409.         if (!Examine(FL, FIB))
  410.         {
  411.           ErrorHandle(DESTROYEDENTRY);
  412.           fprintf(stderr,"%s'. Very strange!\n", path);
  413.           Error= true;
  414.         }
  415.         else
  416.           if (!path) Append(FIB->fib_FileName, true);
  417.  
  418.         if (!Error)
  419.          while (FL)
  420.          {
  421.            while (FL && ExNext(FL, FIB) && !Error)
  422.            {
  423.              if (Match(FIB->fib_FileName, fpat))  /*Compare filename&pattern*/
  424.              {
  425.                BOOL found= false;
  426.  
  427.                if (FIB->fib_DirEntryType >= 0L)      /** => it is a dirname **/
  428.                {
  429.                  if (!(options & FILESONLY))
  430.                  {
  431.                    fprintf(stdout, "%s%s", MPath, FIB->fib_FileName);
  432.  
  433.                    if (options & SIZE)
  434.                       fprintf(stdout, " (dir) ");
  435.  
  436.                    if (options & TIME)
  437.                       printdate(&(FIB->fib_Date));
  438.                    fprintf(stdout, "\n");
  439.                    if (options & JUMPDIR)
  440.                       found= true;
  441.                  }
  442.                }
  443.                else                                 /** => it is a filename **/
  444.                if (!(options & DIRSONLY))
  445.                {
  446.                  fprintf(stdout, "%s%s", MPath, FIB->fib_FileName);
  447.  
  448.                  if (options & SIZE)
  449.                      fprintf(stdout, " %ld",FIB->fib_Size);
  450.                  if (options & TIME)
  451.                     printdate(&(FIB->fib_Date));
  452.                  fprintf(stdout, "\n");
  453.                  if (options & JUMPDIR)
  454.                     found= true;
  455.                }
  456.                if (found)
  457.                {
  458.                  if (SwitchRaw(ON))
  459.                     Error= true;
  460.                  else
  461.                  {
  462.                    int c;
  463.  
  464.                    fprintf(stderr,"Change to that dir? [yNq]:");
  465.                    c= getchar();
  466.                    fprintf(stderr,"%c\n", c);
  467.                    SwitchRaw(OFF);
  468.  
  469.                    if (toupper(c)=='Y')
  470.                    {
  471.                      struct FileLock *CDL;
  472.                      struct CommandLineInterface *CLI;
  473.                      char *i;
  474.                      int p;
  475.  
  476.                      if (FIB->fib_DirEntryType >= 0L)
  477.                         Append(FIB->fib_FileName, false);
  478.                      /* if Directory found append it to mpath, cause we'll: */
  479.  
  480.                      /* change the current dir */
  481.  
  482.                      CDL=(struct FileLock *) Lock(MPath, (ULONG) ACCESS_READ);
  483.                      if (!CDL)
  484.                      {
  485.                        ErrorHandle(STRANGE);
  486.                        Error= true;
  487.                      }
  488.                      CDL= CurrentDir(CDL);
  489.                      UnLock(CDL);
  490.                      /* The new-lock must be retained and can't be unlocked,
  491.                         the old one must be unlocked */
  492.  
  493.                      CLI=(struct CommandLineInterface *)
  494.                           BADDR(myprocess->pr_CLI);
  495.                      i= (char *) ((CLI->cli_SetName) << 2);
  496.  
  497.                      /* Copy the new name to CLI */
  498.                      for (p=0; MPath[p]!='\0'; p++)
  499.                          *(i+p+1)= MPath[p];
  500.                      if (MPath[p-1]=='/')
  501.                      {
  502.                        *i= (char) (p-1);
  503.                      }
  504.                      else
  505.                        *i= (char) p;
  506.  
  507.                      if (FIB->fib_DirEntryType >= 0L)
  508.                         Cut();
  509.  
  510.                      Error= true;
  511.                    }
  512.                    if (toupper(c)=='Q')
  513.                    {
  514.                      Error= true;
  515.                      fprintf(stdout,"Quit!\n");
  516.                    }
  517.                  }
  518.                }
  519.              }
  520.  
  521.              if (FIB->fib_DirEntryType >= 0L) /* Dirname? Climb down the tree */
  522.              {
  523.                if (!(options & NOSUBDIRS))
  524.                {
  525.                  Append(FIB->fib_FileName, false);
  526.                  LChainP->FLock= FL;
  527.                  LChainP->prev = OldLChainP;
  528.                  OldLChainP= LChainP;
  529.                  cbuf= MPath[MPathPos-1]; MPath[MPathPos-1]= '\0';
  530.                  FL=(struct FileLock *) Lock(MPath, (ULONG) ACCESS_READ);
  531.                  MPath[MPathPos-1]= cbuf;
  532.                  if (!FL)
  533.                  {
  534.                    ErrorHandle(STRANGE);
  535.                    Error= true;
  536.                  }
  537.                  else
  538.                  {
  539.                    LChainP= (struct ListType *) AllocMem
  540.                          ((long) sizeof(struct ListType), MEMTYPE);
  541.  
  542.                    if (!LChainP)
  543.                    {
  544.                      ErrorHandle(NOMEM);
  545.                      Error= true;
  546.                      UnLock(FL);           /* Free last Lock */
  547.                      LChainP= OldLChainP;  /* To free the whole list */
  548.                      FL= OldLChainP->FLock; /* Get actual Lock */
  549.                      OldLChainP= OldLChainP->prev;
  550.                    }
  551.                    else
  552.                    {
  553.                      FIB= &LChainP->FIBlock;
  554.                      Examine(FL, FIB);
  555.                    }
  556.                  }
  557.                }
  558.              }
  559.            }            /* Climb-up-the-tree section*/
  560.            if (SetSignal(NULL, NULL) & (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D))
  561.            {
  562.              SetSignal(NULL, (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D));
  563.              if (!Error)
  564.              {
  565.                 fprintf(stderr, "** BREAK **\n"); /* Just print one break */
  566.                 Error= true;
  567.              }
  568.            }
  569.            if (LChainP)    /* Is there still an entry? */
  570.            {
  571.              UnLock(FL);   /* Free actual Lock */
  572.              Cut();
  573.              FreeMem (LChainP, (long) sizeof(struct ListType));
  574.              if (OldLChainP)        /* Get next entry to free,climb up list */
  575.              {
  576.                FL = OldLChainP->FLock;
  577.                FIB= &OldLChainP->FIBlock;
  578.                LChainP= OldLChainP;
  579.                OldLChainP= OldLChainP->prev;
  580.              }
  581.              else                  /* Last entry reached */
  582.              {
  583.                FL= NULL;
  584.                LChainP= NULL;
  585.              }
  586.            }
  587.            else
  588.              FL= NULL;  /* No more entries? -> leave while loop */
  589.          }
  590.       }
  591.     }
  592.   }
  593.   if (LChainP) FreeMem (LChainP,(long) sizeof(struct ListType));
  594.   if (OldLChainP) FreeMem (OldLChainP,(long) sizeof(struct ListType));
  595.   if (FL) UnLock (FL);
  596.  
  597.   return Error;
  598. }
  599.  
  600.                  /******* main(), what else? *******/
  601.  
  602. main(argc, argv)
  603. int argc;
  604. char **argv;
  605.  
  606. {
  607.   int i1, i2, findx= 0;
  608.   char *args[2], *patharg=NULL, *filepattern=NULL;
  609.  
  610.  
  611.   Enable_Abort= 0;                     /*** No Ctrl-C please!!! ***/
  612.   args[0]= args[1]= NULL;
  613.   prgname= *argv;
  614.  
  615.   SetSignal(NULL, (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D));   /*** Clear Ctrl-D signal ***/
  616.  
  617.   if (argc == 1)
  618.   {
  619.     ErrorHandle(USAGE);
  620.     exit(RETURN_OK);
  621.   }
  622.  
  623.   for (i1= 1; i1 != argc; i1++)
  624.   {
  625.       if (*argv[i1] == '-')
  626.          for (i2= 1; argv[i1][i2] != '\0'; i2++)
  627.          {
  628.            switch (argv[i1][i2])
  629.            {
  630.              case 'a': options|= SIZE | TIME;
  631.                        break;
  632.  
  633.              case 'c': options|= CASESENSITIVE;
  634.                        break;
  635.  
  636.              case 'd': options|= DIRSONLY;
  637.                        break;
  638.  
  639.              case 'f': options|= FILESONLY;
  640.                        break;
  641.  
  642.              case 'i': ErrorHandle(USAGE);
  643.                        ErrorHandle(INFO);
  644.                        exit(RETURN_OK);
  645.                        break;
  646.  
  647.              case 'j': if (IsInteractive(Input()))
  648.                        {
  649.                          myprocess= (struct Process *) FindTask(NULL);
  650.                          conid = (struct MsgPort *) myprocess->pr_ConsoleTask;
  651.                                  /* get con-handler */
  652.                          options|= (JUMPDIR | LONGPATH);
  653.                        }
  654.                        else
  655.                        {
  656.                          ErrorHandle(NOINPUT);
  657.                          exit(RETURN_FAIL);
  658.                        }
  659.  
  660.                        break;
  661.  
  662.              case 'n': options|= NOSUBDIRS;
  663.                        break;
  664.  
  665.              case 'p': options|= LONGPATH;
  666.                        break;
  667.  
  668.              case 's': options|= SIZE;
  669.                        break;
  670.  
  671.              case 't': options|= TIME;
  672.                        break;
  673.  
  674.  
  675.              default : ErrorHandle(ILLEGALOPTION);
  676.                        fprintf(stderr,"%c' !\n", argv[i1][i2]);
  677.                        ErrorHandle(USAGE);
  678.                        exit (RETURN_ERROR);
  679.                        break;
  680.            }
  681.          }
  682.       else
  683.       {
  684.         if (findx > 1)
  685.         {
  686.           ErrorHandle(TOOMANYARGS);
  687.           exit (RETURN_ERROR);
  688.         }
  689.         else
  690.         {
  691.           args[findx]= argv[i1]; findx++;
  692.         }
  693.       }
  694.   }
  695.  
  696.   if (findx==0)
  697.   {
  698.     ErrorHandle(NOPATTERN);
  699.     ErrorHandle(USAGE);
  700.     exit(RETURN_ERROR);
  701.   }
  702.   for (i1= 0; i1 < 2; i1++)
  703.   {
  704.     if (args[i1] != NULL)
  705.     {
  706.       for (i2= 0; (c= args[i1][i2]) != '\0' && c != ':' && c != '/';i2++);
  707.  
  708.       if (c != '\0')
  709.          patharg= args[i1];
  710.       else
  711.          filepattern= args[i1];
  712.     }
  713.   }
  714.   if (findx == 2 && !patharg)
  715.   {
  716.      patharg= args[0];
  717.      filepattern= args[1];
  718.   }
  719.  
  720.   if (Search(patharg, filepattern) == true)
  721.   {
  722.     fprintf(stderr, "%s-- Aborted!\n", prgname);
  723.     exit(RETURN_ERROR);
  724.   }
  725. }
  726.